package com.github.baichuan.application.scaffold.domain.authorization;

import com.github.baichuan.application.scaffold.domain.application.Application;
import com.github.baichuan.application.scaffold.domain.application.ApplicationService;
import com.github.baichuan.application.scaffold.dto.resource.PageForm;
import com.github.baichuan.application.scaffold.jpa.authorization.ResourceRepository;
import com.github.baichuan.web.dto.Result;
import com.github.baichuan.utils.SnowFlake;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Optional;

@Service
@Transactional(rollbackFor = Exception.class)
public class PageService {
    @Autowired
    private ResourceRepository resourceRepository;
    @Autowired
    private ResourceService resourceService;
    @Autowired
    private ApplicationService applicationService;
    @Autowired
    private SnowFlake snowFlake;

    public Resource find(String id){
        Resource resource = resourceService.find(id);
        if(resource.getKind() != Resource.Kind.page)
            throw new RuntimeException("资源类型错误");
        return resource;
    }

    public Resource find(String application, String id){
        Resource resource = resourceService.find(application, id);
        if(resource.getKind() != Resource.Kind.page)
            throw new RuntimeException("资源类型错误");
        return resource;
    }


    public Result add(String applicationCode, PageForm form){
        Application application = applicationService.findByCode(applicationCode.trim());
        Resource parent = null;
        if (StringUtils.isNotBlank(form.getParentId()))
            parent = resourceService.find(applicationCode, form.getParentId());

        Optional<Resource> duplication = resourceRepository.findByCode(application, form.getCode().trim());
        if (duplication.isPresent()) {
            return Result.fail("资源代码重复");
        }

        Resource resource = new Resource();
        resource.setId(snowFlake.nextBase62Id().substring(4));
        resource.setApplication(application);
        resource.setKind(Resource.Kind.page);
        merge(form, resource);

        if (null != form.getParentId()) {
            resource.setParent(parent);
        }
        resourceRepository.save(resource);

        return Result.success("页面保存成功", resource.getId());
    }

    public Result edit(String applicationCode, String id, PageForm form) {
        Application application = applicationService.findByCode(applicationCode.trim());

        Optional<Resource> duplication = resourceRepository.findByCode(application, form.getCode().trim());
        if (duplication.isPresent() && !duplication.get().getId().equals(id)) {
            return Result.fail("资源代码重复");
        }

        Resource resource = find(id);
        if (!resource.getApplication().getCode().equals(application.getCode())) {
            return Result.fail("平台编码错误");
        }

        merge(form, resource);

        if (form.getParentId() != null) {
            Resource parent = resourceService.find(applicationCode, form.getParentId());
            if (!resource.checkCycle(parent)) {
                resource.setParent(parent);
            } else {
                return Result.fail("父菜单存在循环引用");
            }
        } else {
            resource.setParent(null);
        }

        resourceRepository.save(resource);
        return Result.success("页面保存成功");
    }

    private void merge(PageForm from, Resource to) {
        to.setName(from.getName().trim());
        to.setCode(from.getCode().trim());
        to.setRoute(from.getRoute().trim());
        to.setPath(from.getPath().trim());
        to.setSort(from.getSort());
    }
}
